package com.jyoume.yudao.generator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.logging.Log;

import java.io.File;
import java.util.*;

/**
 * 基于MyBatisPlus的代码生成器
 *
 * @author sing
 */
public class CodeGenerator {
    /**
     * 项目模块
     */
    String module;
    /**
     * 业务模块
     */
    String bizModule;
    /**
     * 是否生成Excel导入导出代码
     */
    static boolean excelCodeGenerate = false;
    /**
     * 是否生成AppController代码
     */
    static boolean appControllerCodeGenerate = false;
    /**
     * 是否为树形结构表
     */
    static boolean isTreeTable = false;
    /**
     * 是否异步加载树形结构数据
     */
    static boolean lazyTree = true;

    static String company = "petbox";
    /**
     * 树形结构表父ID字段属性名称
     */
    static final String PARENT_ID = "parentId";
    /**
     * 默认使用的Vue视图模板
     */
    static String vueViewTemp = "view.vue.vm";
    /**
     * UI项目所在的路径
     */
    static String uiProjectPath = "admin-ui";
    static String databaseUrl;
    static String username;
    static String password;
    static String version = "1.0.0";
    static String tablePrefix = "t_";

    private final Log log;

    /**
     * 获取TemplateConfig
     *
     * @return TemplateConfig
     */
    private TemplateConfig getTemplateConfig() {
        TemplateConfig tc = new TemplateConfig();
        //关闭默认xml生成
        tc.setXml(null);
        /*
          自动生成代码到相应的module，避免手动拷贝代码文件
         */
        /*if ("repository".equals(module)) {
            //如果当前模块是repository，不生成controller和service
            tc.setController(null);
            tc.setService(null);
            tc.setServiceImpl(null);
        } else if ("base-rest".equals(module)) {
            //如果当前模块是base-rest，不生成mapper和entity和xml
            tc.setMapper(null);
            tc.setEntity(null);
        }*/
        return tc;
    }

    /**
     * 获取InjectionConfig
     *
     * @return InjectionConfig
     */
    private InjectionConfig getInjectionConfig() {
        String bizModulePath = bizModule.replace(".", "/");
        //添加自定义模板文件
        List<FileOutConfig> fileOutConfigList = new ArrayList<>();
        FileOutConfig fileDto = new FileOutConfig("/templates/dto.java.vm") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                String dtoFileName = tableInfo.getEntityName().substring(0, tableInfo.getEntityName().lastIndexOf("Entity")) + "Dto.java";
                if (StringUtils.isNoneBlank(bizModulePath)) {
                    return getJavaPath() + "/com/" + company + "/" + bizModulePath + "/dto/" + dtoFileName;
                } else {
                    return getJavaPath() + "/com/" + company + "/dto/" + dtoFileName;
                }

            }
        };
        FileOutConfig fileVo = new FileOutConfig("/templates/vo.java.vm") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                String voFileName = tableInfo.getEntityName().substring(0, tableInfo.getEntityName().lastIndexOf("Entity")) + "Vo.java";
                if (StringUtils.isNoneBlank(bizModulePath)) {
                    return getJavaPath() + "/com/" + company + "/" + bizModulePath + "/vo/" + voFileName;
                } else {
                    return getJavaPath() + "/com/" + company + "/vo/" + voFileName;
                }
            }
        };

        FileOutConfig fileQuery = new FileOutConfig("/templates/query.java.vm") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                String queryFileName = tableInfo.getEntityName().substring(0, tableInfo.getEntityName().lastIndexOf("Entity")) + "ReqVo.java";
                if (StringUtils.isNoneBlank(bizModulePath)) {
                    return getJavaPath() + "/com/" + company + "/" + bizModulePath + "/vo/" + queryFileName;
                } else {
                    return getJavaPath() + "/com/" + company + "/vo/" + queryFileName;
                }
            }
        };

        FileOutConfig fileConverter = new FileOutConfig("/templates/converter.java.vm") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                String converterFileName = tableInfo.getEntityName().substring(0, tableInfo.getEntityName().lastIndexOf("Entity")) + "Converter.java";
                if (StringUtils.isNoneBlank(bizModulePath)) {
                    return getJavaPath() + "/com/" + company + "/" + bizModulePath + "/converter/" + converterFileName;
                } else {
                    return getJavaPath() + "/com/" + company + "/converter/" + converterFileName;
                }
            }
        };
        //如果配置了UI项目的路径则生成UI相关代码
        if (StringUtils.isNoneBlank(uiProjectPath)) {
            log.info("生成UI相关代码:" + uiProjectPath);
            File file = new File(uiProjectPath);
            if (!file.exists()) {
                boolean retVal = file.mkdirs();
                if (retVal) {
                    log.info("创建前端UI项目" + uiProjectPath + "目录成功");
                }
            }
            FileOutConfig apiTs = new FileOutConfig("/templates/vue/api.ts.vm") {
                // 自定义输出文件目录
                @Override
                public String outputFile(TableInfo tableInfo) {
                    String entityPath = tableInfo.getEntityPath();
                    if (StringUtils.isNoneBlank(bizModule)) {
                        if (tableInfo.getEntityPath().startsWith(bizModule)) {
                            entityPath = tableInfo.getEntityPath().substring(bizModule.length());
                            entityPath = entityPath.substring(0, 1).toLowerCase() + entityPath.substring(1);
                        }
                        entityPath = entityPath.replace("Entity", "");
                        String savePath = uiProjectPath + "/src/views/modules/" + bizModulePath;
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        return savePath + "/" + entityPath + "/api.ts";
                    } else {
                        String savePath = uiProjectPath + "/src/views/modules";
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        return savePath + "/" + "api.ts";
                    }

                }
            };
            FileOutConfig formDataTs = new FileOutConfig("/templates/vue/form.data.ts.vm") {
                // 自定义输出文件目录
                @Override
                public String outputFile(TableInfo tableInfo) {
                    String entityPath = tableInfo.getEntityPath();
                    if (StringUtils.isNoneBlank(bizModule)) {
                        if (tableInfo.getEntityPath().startsWith(bizModule)) {
                            entityPath = tableInfo.getEntityPath().substring(bizModule.length());
                            entityPath = entityPath.substring(0, 1).toLowerCase() + entityPath.substring(1);
                        }
                        entityPath = entityPath.replace("Entity", "");
                        String savePath = uiProjectPath + "/src/views/modules/" + bizModulePath;
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        return savePath + "/" + entityPath + "/form.data.ts";
                    } else {
                        String savePath = uiProjectPath + "/src/views/modules";
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        return savePath + "/" + "form.data.ts";
                    }

                }
            };
            FileOutConfig indexVueView = new FileOutConfig("/templates/vue/index.vue.vm") {
                // 自定义输出文件目录
                @Override
                public String outputFile(TableInfo tableInfo) {
                    String entityPath = tableInfo.getEntityPath();
                    String outputFile = "";
                    if (StringUtils.isNoneBlank(bizModule)) {
                        if (tableInfo.getEntityPath().startsWith(bizModule)) {
                            entityPath = tableInfo.getEntityPath().substring(bizModule.length());
                            entityPath = entityPath.substring(0, 1).toLowerCase() + entityPath.substring(1);
                        }
                        entityPath = entityPath.replace("Entity", "");
                        String savePath = uiProjectPath + "/src/views/modules/" + bizModulePath + "/" + entityPath;
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        outputFile = savePath + "/index.vue";
                    } else {
                        String savePath = uiProjectPath + "/src/views/modules/" + entityPath;
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        outputFile = savePath + "/views/index.vue";
                    }
                    log.info(">>>>" + outputFile);
                    return outputFile;
                }
            };
            FileOutConfig editFormVueView = new FileOutConfig("/templates/vue/EditForm.vue.vm") {
                // 自定义输出文件目录
                @Override
                public String outputFile(TableInfo tableInfo) {
                    String entityPath = tableInfo.getEntityPath();
                    String outputFile = "";
                    if (StringUtils.isNoneBlank(bizModule)) {
                        if (tableInfo.getEntityPath().startsWith(bizModule)) {
                            entityPath = tableInfo.getEntityPath().substring(bizModule.length());
                            entityPath = entityPath.substring(0, 1).toLowerCase() + entityPath.substring(1);
                        }
                        entityPath = entityPath.replace("Entity", "");
                        String savePath = uiProjectPath + "/src/views/modules/" + bizModulePath + "/" + entityPath;
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        outputFile = savePath + "/EditForm.vue";
                    } else {
                        String savePath = uiProjectPath + "/src/views/modules/" + entityPath;
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        outputFile = savePath + "/EditForm.vue";
                    }
                    log.info(">>>>" + outputFile);
                    return outputFile;
                }
            };

            fileOutConfigList.add(apiTs);
            fileOutConfigList.add(formDataTs);
            fileOutConfigList.add(indexVueView);
            fileOutConfigList.add(editFormVueView);
        }
        fileOutConfigList.add(fileDto);
        fileOutConfigList.add(fileVo);
        fileOutConfigList.add(fileQuery);
        fileOutConfigList.add(fileConverter);
        if (excelCodeGenerate) {
            FileOutConfig fileImporter = new FileOutConfig("/templates/importer.java.vm") {
                // 自定义输出文件目录
                @Override
                public String outputFile(TableInfo tableInfo) {
                    if (StringUtils.isNoneBlank(bizModulePath)) {
                        return getJavaPath() + "/com/" + company + "/" + bizModulePath + "/excel/" + tableInfo.getEntityName() + "Importer.java";
                    } else {
                        return getJavaPath() + "/com/" + company + "/excel/" + tableInfo.getEntityName() + "Importer.java";
                    }

                }
            };
            fileOutConfigList.add(fileImporter);
        }

        /*if (isTreeTable) {
            FileOutConfig fileTreeVo = new FileOutConfig("/templates/treeVo.java.vm") {
                // 自定义输出文件目录
                @Override
                public String outputFile(TableInfo tableInfo) {
                    if (StringUtils.isNoneBlank(bizModule)) {
                        return getJavaPath() + "/com/" + company + "/" + bizModulePath + "/vo/" + tableInfo.getEntityName() + "TreeVo.java";
                    } else {
                        return getJavaPath() + "/com/" + company + "/vo/" + tableInfo.getEntityName() + "TreeVo.java";
                    }

                }
            };
            fileOutConfigList.add(fileTreeVo);
        }*/

        if (appControllerCodeGenerate) {
            FileOutConfig appController = new FileOutConfig("/templates/apiController.java.vm") {
                // 自定义输出文件目录
                @Override
                public String outputFile(TableInfo tableInfo) {
                    if (StringUtils.isNoneBlank(bizModule)) {
                        String savePath = getJavaPath() + "/com/" + company + "/" + bizModulePath + "/app/controller";
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        return savePath + "/" + tableInfo.getControllerName().replace("Admin", "App") + ".java";
                    } else {
                        String savePath = getJavaPath() + "/com/" + company + "/app/controller";
                        File dir = new File(savePath);
                        if (!dir.exists()) {
                            if (!dir.mkdirs() && !dir.exists()) {
                                log.warn("Failed to create directory: " + dir.getAbsolutePath());
                            }
                        }
                        return savePath + "/" + tableInfo.getControllerName().replace("Admin", "App") + ".java";
                    }
                }
            };
            fileOutConfigList.add(appController);
        }

        FileOutConfig fileMapperXml = new FileOutConfig("/templates/mapper.xml.vm") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                String mapperXmlFileName = tableInfo.getEntityName().substring(0, tableInfo.getEntityName().lastIndexOf("Entity")) + "Mapper.xml";
                if (StringUtils.isNoneBlank(bizModule)) {
                    String savePath = getResourcePath() + "/mapper/" + bizModulePath;
                    File dir = new File(savePath);
                    if (!dir.exists()) {
                        if (!dir.mkdirs() && !dir.exists()) {
                            log.warn("Failed to create directory: " + dir.getAbsolutePath());
                        }
                    }
                    return savePath + "/" + mapperXmlFileName;
                } else {
                    String savePath = getResourcePath() + "/mapper/";
                    File dir = new File(savePath);
                    if (!dir.exists()) {
                        if (!dir.mkdirs() && !dir.exists()) {
                            log.warn("Failed to create directory: " + dir.getAbsolutePath());
                        }
                    }
                    return savePath + mapperXmlFileName;
                }
            }
        };
        fileOutConfigList.add(fileMapperXml);
        //注入自定义配置
        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
                map.put("parentGroupId", "com." + company);
                map.put("parentArtifactId", "");
                map.put("excelCodeGenerate", excelCodeGenerate);
                map.put("isTreeTable", isTreeTable);
                map.put("version", version);
                map.put("tablePrefix", tablePrefix);
                if (isTreeTable) {
                    map.put("lazyTree", lazyTree);
                    map.put("pId", PARENT_ID);
                }
                this.setMap(map);
            }
        };
        injectionConfig.setFileOutConfigList(fileOutConfigList);
        /*
         * 由于实际项目中，表字段有增减，编写的service或者controller方法不需要重复生成，可以进行定制开发来设置 ，目前根据实际项目需要
         ,对已存在的文件，只要对 entity 和mapper 进行重复生成
         */
        injectionConfig.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判断自定义文件夹是否需要创建,这里调用默认的方法
                checkDir(filePath);
                //对于已存在的文件，只需重复生成entity
                File file = new File(filePath);
                /*boolean exist = file.exists();
                if (exist) {
                    if (FileType.ENTITY == fileType) {
                        return true;
                    } else {
                        return false;
                    }
                }*/
                //不存在的文件都需要创建
                return true;
            }
        });
        return injectionConfig;
    }

    /**
     * 获取PackageConfig
     *
     * @return PackageConfig
     */
    private PackageConfig getPackageConfig() {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig
                .setParent("com." + company)
                .setController("controller.admin")
                .setEntity("repository.entity")
                .setMapper("repository.mapper")
                .setService("service")
                .setServiceImpl("service.impl");
        if (StringUtils.isNotEmpty(bizModule)) {
            packageConfig
                    .setParent("com." + company)
                    .setModuleName(bizModule);
        }

        return packageConfig;
    }

    /**
     * 获取StrategyConfig
     *
     * @param tableName 表名· ·····
     * @return StrategyConfig
     */
    private StrategyConfig getStrategyConfig(String... tableName) {
        return new StrategyConfig()
                // 全局大写命名
                .setCapitalMode(false)
                // 去除前缀
                .setTablePrefix(tablePrefix)
                // 表名生成策略
                .setNaming(NamingStrategy.underline_to_camel)
                //.setInclude(new String[] { "user" }) // 需要生成的表
                //自定义实体父类
                //.setSuperEntityClass("com." + COM + ".core.repository.entity.BaseEntity")
                // 自定义实体，公共字段
                //.setSuperEntityColumns("id")
                .setTableFillList(getTableFills())
                ////逻辑删除标识
                .setLogicDeleteFieldName("deleted")
                // 自定义 mapper 父类
                //.setSuperMapperClass("com." + COM + ".mapper.BaseMapper")
                // 自定义 controller 父类
                //.setSuperControllerClass("com." + company + ".commons.base.SuperController")
                // 自定义 service 实现类父类
                //.setSuperServiceImplClass("com." + COM + ".service.impl.BaseServiceImpl")
                // 自定义 service 接口父类
                //.setSuperServiceClass("com." + COM + ".service.BaseService")
                // 【实体】是否生成字段常量（默认 false）
                .setEntityColumnConstant(false)
                // 【实体】是否为构建者模型（默认 false）
                .setChainModel(false)
                // 【实体】是否为lombok模型（默认 false）<a href="https://projectlombok.org/">document</a>
                .setEntityLombokModel(true)
                // Boolean类型字段是否移除is前缀处理
                .setEntityBooleanColumnRemoveIsPrefix(true)
                .setRestControllerStyle(true)
                .setInclude(tableName);
    }

    /**
     * 获取TableFill策略
     *
     * @return TableFill策略
     */
    private List<TableFill> getTableFills() {
        // 自定义需要填充的字段
        List<TableFill> tableFillList = new ArrayList<>();
        tableFillList.add(new TableFill("create_time", FieldFill.INSERT));
        tableFillList.add(new TableFill("update_time", FieldFill.INSERT_UPDATE));
        tableFillList.add(new TableFill("creator", FieldFill.INSERT));
        tableFillList.add(new TableFill("updater", FieldFill.INSERT_UPDATE));
        tableFillList.add(new TableFill("deleted", FieldFill.INSERT));
        tableFillList.add(new TableFill("tenant_id", FieldFill.INSERT));
        return tableFillList;
    }

    /**
     * 获取DataSourceConfig
     *
     * @return DataSourceConfig
     */
    private DataSourceConfig getDataSourceConfig() {
        DbType dbType = DbType.MARIADB;
        String driverName = "com.mysql.cj.jdbc.Driver";
        ITypeConvert typeConvert = new MySqlTypeConvert() {
            @Override
            public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                if ("bit".equalsIgnoreCase(fieldType)) {
                    return DbColumnType.BOOLEAN;
                }
                if ("tinyint".equalsIgnoreCase(fieldType)) {
                    return DbColumnType.INTEGER;
                }
                if ("date".equalsIgnoreCase(fieldType)) {
                    return DbColumnType.LOCAL_DATE;
                }
                if ("time".equalsIgnoreCase(fieldType)) {
                    return DbColumnType.LOCAL_TIME;
                }
                if ("datetime".equalsIgnoreCase(fieldType)) {
                    return DbColumnType.LOCAL_DATE_TIME;
                }
                if ("timestamp".equalsIgnoreCase(fieldType)) {
                    return DbColumnType.LOCAL_DATE_TIME;
                }
                if ("bigint".equalsIgnoreCase(fieldType)) {
                    return DbColumnType.LONG;
                }
                return super.processTypeConvert(globalConfig, fieldType);
            }
        };
        if (databaseUrl.contains("postgresql")) {
            dbType = DbType.POSTGRE_SQL;
            driverName = "org.postgresql.Driver";
        }
        return new DataSourceConfig()
                // 数据库类型
                .setDbType(dbType)
                .setTypeConvert(typeConvert)
                .setDriverName(driverName)
                .setUsername(username)
                .setPassword(password)
                .setUrl(databaseUrl);
    }

    /**
     * 获取GlobalConfig
     *
     * @return GlobalConfig
     */
    private GlobalConfig getGlobalConfig() {

        return new GlobalConfig()
                //输出目录
                .setOutputDir(getJavaPath())
                // 是否覆盖文件
                .setFileOverride(true)
                // 开启 activeRecord 模式
                .setActiveRecord(false)
                // XML 二级缓存
                .setEnableCache(false)
                // XML ResultMap
                .setBaseResultMap(false)
                // XML columList
                .setBaseColumnList(false)
                //是否生成 kotlin 代码
                .setKotlin(false)
                .setOpen(false)
                //生成swagger注解
                .setSwagger2(false)
                //作者
                .setAuthor("Generator by " + System.getProperty("user.name"))
                //自定义文件命名，注意 %s 会自动填充表实体属性！
                .setXmlName("%sMapper")
                .setServiceName("%sService")
                .setServiceImplName("%sServiceImpl")
                .setEntityName("%sEntity")
                .setMapperName("%sMapper")
                .setControllerName("%sAdminController");
    }


    /**
     * 获取根目录
     *
     * @return 目录
     */
    private String getRootPath() {
        return System.getProperty("user.dir");
    }

    /**
     * 获取JAVA目录
     *
     * @return 目录
     */
    private String getJavaPath() {
        String javaPath;
        if (StringUtils.isNotEmpty(module)) {
            File file = new File(module);
            javaPath = file.getAbsolutePath() + "/target/generated-sources/java";
        } else {
            javaPath = getRootPath() + "/target/generated-sources/java";
        }
        System.err.println(" Generator Java Path:【 " + javaPath + " 】");
        return javaPath;
    }

    /**
     * 获取Resource目录
     *
     * @return 目录
     */
    protected String getResourcePath() {
        String resourcePath = getRootPath() + "/src/main/resources";
        if (StringUtils.isNotEmpty(module)) {
            File file = new File(module);
            resourcePath = file.getAbsolutePath() + "/src/main/resources";
        }
        System.err.println(" Generator Resource Path:【 " + resourcePath + " 】");
        return resourcePath;
    }

    /**
     * 获取AutoGenerator
     *
     * @param tableName 表名
     * @return AutoGenerator
     */
    private AutoGenerator getAutoGenerator(String... tableName) {
        return new AutoGenerator()
                // 全局配置
                .setGlobalConfig(getGlobalConfig())
                // 数据源配置
                .setDataSource(getDataSourceConfig())
                // 策略配置
                .setStrategy(getStrategyConfig(tableName))
                // 包配置
                .setPackageInfo(getPackageConfig())
                // 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
                .setCfg(getInjectionConfig())
                .setTemplate(getTemplateConfig());
    }

    /**
     * 生成代码
     *
     * @param bizModule 指定业务模块名称，例如：系统模块
     * @param tableName 数据表
     */
    public void generator(String bizModule, String... tableName) {
        this.bizModule = bizModule;
        // 代码生成器
        AutoGenerator mpg = getAutoGenerator(tableName);
        mpg.execute();
        if (tableName == null) {
            System.err.println(" Generator Success !");
        } else {
            System.err.println(" Generator Success : " + Arrays.toString(tableName));
        }
    }

    public CodeGenerator(Log log, String module) {
        this.module = module;
        this.log = log;
    }
}
